這篇就做一件事:把 網頁上的
<canvas>
交給顯示卡,然後用 WebGPU 把畫面清成你指定的顏色。
你會學到:準備環境 → 建專案骨架 → 取得 Adapter / Device → 設定 Canvas Context(呈現格式)→ 錄一個最簡的「清畫面」指令。
navigator.gpu
是 undefined
,多半是瀏覽器太舊或沒在「安全環境(https 或 localhost)」執行。navigator.gpu
—— 若不是 undefined
就 OK。file://
)常會失敗,所以我們會用一個小型開發伺服器。檔案結構
webgpu-hello/
├─ index.html
└─ main.js
index.html
<!doctype html>
<html lang="zh-Hant">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>WebGPU Hello</title>
<style>
html,body { height:100%; margin:0; background:#0b1220; }
canvas { width: 100vw; height: 100vh; display:block; }
</style>
</head>
<body>
<canvas id="gfx"></canvas>
<script type="module" src="./main.js"></script>
</body>
</html>
main.js(一步步做初始化+清畫面)
// 1) 取得 WebGPU 入口
if (!('gpu' in navigator)) {
alert('這個瀏覽器尚未支援 WebGPU,或不是在 https/localhost。');
throw new Error('WebGPU not supported');
}
// 2) 找一張可用的顯示卡(Adapter),再要一個 Device(邏輯裝置)
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw new Error('找不到可用的顯示卡(adapter)');
const device = await adapter.requestDevice();
// 3) 取得 Canvas 的 WebGPU Context,並設定「呈現格式」
const canvas = document.getElementById('gfx');
const context = canvas.getContext('webgpu');
// 推薦:用瀏覽器建議的格式(不同平台會對應正確的色彩格式)
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
function resizeCanvasToDisplaySize() {
// 把 CSS 尺寸(視窗大小)換成實際像素大小(含裝置像素比)
const dpr = Math.min(2, window.devicePixelRatio || 1);
const width = Math.floor(canvas.clientWidth * dpr);
const height = Math.floor(canvas.clientHeight * dpr);
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
}
context.configure({
device,
format: presentationFormat,
alphaMode: 'opaque' // 不需要透明合成時,opaque 最高效
});
}
resizeCanvasToDisplaySize();
window.addEventListener('resize', resizeCanvasToDisplaySize);
// 4) 清畫面(把畫面塗成你想要的顏色)
function frame() {
const encoder = device.createCommandEncoder();
// 取得當前可寫入的貼圖(就像 swapchain 的下一張)
const view = context.getCurrentTexture().createView();
const pass = encoder.beginRenderPass({
colorAttachments: [{
view,
clearValue: { r: 0.06, g: 0.10, b: 0.18, a: 1.0 }, // 想清成什麼顏色就改這裡
loadOp: 'clear', // 進場先清掉上一幀
storeOp: 'store' // 出場把結果留下來(呈現)
}]
});
pass.end();
device.queue.submit([encoder.finish()]);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
啟動小伺服器
# 任何一種都行,選你順手的
npx serve . # 或
python -m http.server # 或
npx http-server .
開瀏覽器到顯示的 http://localhost:xxxx
,你應該看到一個深藍底的全螢幕畫面(代表 WebGPU 在跑)。
VkPhysicalDevice
。VkDevice
。所有資源/指令都從它來。webgpu
):把 <canvas>
接上 WebGPU 管線,之後每一幀用 getCurrentTexture()
拿到「這一幀要呈現」的貼圖。getPreferredCanvasFormat()
就能跨平台拿到最合適的那個。navigator.gpu
是 undefined
:瀏覽器太舊、或不是 https/localhost。先升級、改用 dev server。context.configure
沒呼叫、或 canvas.width/height
沒設定(只有 CSS 不算)。devicePixelRatio
做實際像素大小。view
為 undefined
(忘了 createView()
)。configure
;否則可能造成頓卡。alphaMode: 'opaque'
。configure
一下就好。clearValue
,或做一個時間函數 sin(t)
。adapter.features
/ adapter.limits
看看你能做多大貼圖、多複雜的管線。@webgpu/types
,編輯器會自動提示 API。WebGPU 初始化 就是:確認支援 → 取得
adapter/device
→ 對<canvas>
做context.configure
(用建議格式)→ 錄一個清畫面的 render pass →queue.submit
。
當你看見那片你指定顏色的螢幕,代表你已經走通了最核心的一條路,下一步我們就能把 三角形 畫上去,然後把它變成熟悉的「渲染管線」。